package com.gary.spring.webContainer.A01;

import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * @author peng_rui
 * @date 2022/7/10
 */
public class A01Start {
    public static void main(String[] args) throws Exception {
        //创建内嵌式web容器的容器
        AnnotationConfigServletWebServerApplicationContext context =
                new AnnotationConfigServletWebServerApplicationContext(MyWebConfig.class);

        //此处需要手动注入 否则 走默认配置 无法称为spring容器中的bean
        //RequestMappingHandlerMapping 作用，解析 RequestMapping 及其派生注解，生成对应路径与处理器之间的映射关系，在初始化时完成
        RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);

        // 获取映射结果
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        handlerMethods.forEach((k, v) -> {
            System.out.println(k + " ==== " + v);
        });

        // 请求来了，获取控制器方法，返回处理执行链
        // 测试自定义Token 注解请求 GET /testToken
        MockHttpServletRequest request = new MockHttpServletRequest("GET", "/testResponse");
        request.addHeader("token", "tokennnnning");
        MockHttpServletResponse response = new MockHttpServletResponse();
        HandlerExecutionChain chain = handlerMapping.getHandler(request);
        System.out.println(chain);


        //获取映射器适配器
        MyRequestMappingHandlerAdapter handlerAdapter = context.getBean(MyRequestMappingHandlerAdapter.class);
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>.");
        handlerAdapter.invokeHandlerMethod(request, response, (HandlerMethod) chain.getHandler());

        System.out.println(">>>>>>>>>>>>>>>>>>>参数解析器");
        List<HandlerMethodArgumentResolver> argumentResolvers = handlerAdapter.getArgumentResolvers();
        for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) {
            System.out.println(argumentResolver + " -> " + argumentResolver.getClass());
        }


        byte[] contentAsByteArray = response.getContentAsByteArray();
        System.out.println(new String(contentAsByteArray, StandardCharsets.UTF_8));


    }
}
